package com.loves.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.loves.admin.mapper.AccountMapper;
import com.loves.admin.model.Account;
import com.loves.admin.model.User;
import com.loves.admin.model.UserRole;
import com.loves.admin.service.AccountService;
import com.loves.admin.service.UserRoleService;
import com.loves.admin.service.UserService;
import com.loves.admin.util.*;
import com.loves.admin.dto.RegisterDTO;
import com.loves.admin.util.common.Constant;
import com.loves.admin.util.exception.BizException;
import com.loves.admin.vo.LoginVO;
import com.loves.admin.vo.RegisterVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class AccountServiceImpl implements AccountService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private UserService userService;

    private UserRoleService userRoleService;

    @Resource
    private MailUtil mailUtil;

    @Override
    public void mailVerification(String mailName){
        String code = CodeUtil.getMailCode();
        String subject = "发送注册验证码";
        String text = "尊敬的用户，您的验证码为：" + code + ",该验证码15钟内有效，请尽快输入验证注册！";
        if(!mailUtil.sendMail(mailName, subject, text)){
            throw new BizException("验证码发送失败，请重新发送！");
        }
        if (redisUtil.hasKey(mailName)) {
            redisUtil.del(mailName);
        }
        redisUtil.set(mailName, code, 900);
    }

    @Override
    public int existMailName(String mailName) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Account::getMailName, mailName);
        return accountMapper.selectCount(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String register(RegisterDTO registerDTO) {
        //判断验证码是否一致
        if (!redisUtil.get(registerDTO.getMailName()).equals(registerDTO.getCode())) {
            throw new BizException("验证码不一致，请重新输入！");
        }
        Account account = new Account.Builder().mailName(registerDTO.getMailName()).password(MD5Util.string2MD5(registerDTO.getPassword()))
                .createDate(LocalDateTime.now()).createBy("系统").build();
        accountMapper.insert(account);
        User user = userService.initializationUser(account.getMailName(),account.getId());
        userRoleService.insert(user.getId(),Constant.ROLE_ID);
        if (redisUtil.hasKey(account.getMailName())) {
            redisUtil.del(account.getMailName());
        }
        return jwtToken(user,account.getId());
        /*return new RegisterVO.Builder().id(account.getId()).mailName(account.getMailName()).build();*/
    }

    @Override
    public String login(String mailName, String password) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Account::getMailName,mailName).eq(Account::getPassword,MD5Util.string2MD5(password)).eq(Account::getDeleteFlag,false);
        Account account = accountMapper.selectOne(queryWrapper);
        if(account == null){
            throw new BizException("找不到用户名！");
        }
        User user = userService.findByAccountId(account.getId());
        return jwtToken(user,account.getId());


    }

    private String jwtToken(User user,String accountId){
        //载荷
        Map map = new HashMap();
        map.put("id",user.getId());
        map.put("userName",user.getUserName());
        map.put("name",user.getName());
        //生成token
        String token = JwtTokenUtil.createToken(Constant.SUBJECT, map);
        //存入redis缓存
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("id",accountId);
        redisUtil.hmset(token,hashMap);
        return token;
    }

    @Override
    public Account findByMailName(String mailName) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Account::getMailName, mailName).eq(Account::getDeleteFlag,false);
        return accountMapper.selectOne(queryWrapper);
    }
}
